Skip to content

Add opaque metadata passthrough to SDK tool definitions#1864

Merged
stephentoub merged 11 commits into
github:mainfrom
belaltaher8:belaltaher8/tool-meta-passthrough
Jul 15, 2026
Merged

Add opaque metadata passthrough to SDK tool definitions#1864
stephentoub merged 11 commits into
github:mainfrom
belaltaher8:belaltaher8/tool-meta-passthrough

Conversation

@belaltaher8

@belaltaher8 belaltaher8 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Add an optional _metadata bag to the Tool definition (and defineTool) and forward it verbatim over the session.create/resume RPC. This lets hosts attach namespaced, opaque metadata to tools without expanding the typed public contract; unknown keys are round-tripped untouched.

Comment thread nodejs/src/types.ts Outdated
@belaltaher8
belaltaher8 force-pushed the belaltaher8/tool-meta-passthrough branch 2 times, most recently from 68c607d to 6fdc349 Compare July 8, 2026 01:04
@belaltaher8 belaltaher8 changed the title Add opaque _meta passthrough to SDK tool definitions Add opaque metadata passthrough to SDK tool definitions Jul 8, 2026
@belaltaher8
belaltaher8 requested a review from stephentoub July 8, 2026 01:28
@belaltaher8
belaltaher8 marked this pull request as ready for review July 8, 2026 01:54
@belaltaher8
belaltaher8 requested a review from a team as a code owner July 8, 2026 01:54
Copilot AI review requested due to automatic review settings July 8, 2026 01:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional, opaque metadata bag to tool definitions across the multi-language SDKs and forwards it verbatim over session.create / session.resume, enabling hosts to attach namespaced, runtime-recognized (but SDK-opaque) attributes without expanding the typed contract.

Changes:

  • Add metadata to tool definition types/builders (Rust/Go/Node/Python/.NET/Java) with “omit when unset” behavior where applicable.
  • Wire metadata through session create/resume payload construction (Node + Python shown here; others rely on serialization of the definition type).
  • Add/extend unit tests to validate serialization and omission semantics; update Java annotation-processor fixtures for the new constructor arity.
Show a summary per file
File Description
rust/src/types.rs Add Tool.metadata, builder, Debug output, and serialization test.
python/copilot/tools.py Add Tool.metadata + define_tool(..., metadata=...) passthrough.
python/copilot/client.py Include metadata when building tool definitions for create/resume RPCs.
python/test_client.py Add test asserting metadata forwarded on create/resume and omitted when unset.
nodejs/src/types.ts Extend Tool / defineTool types to include optional metadata.
nodejs/src/client.ts Forward tool.metadata into session.create / session.resume payloads.
nodejs/test/client.test.ts Add tests for forwarding and omission of metadata.
go/types.go Add Tool.Metadata with omitempty JSON tag.
go/client_test.go Add serialization tests for tool metadata presence/omission.
dotnet/src/CopilotTool.cs Add MetadataKey + option plumbing into AITool.AdditionalProperties.
dotnet/src/Client.cs Include metadata in internal wire ToolDefinition built from AI function declarations.
dotnet/test/Unit/CopilotToolTests.cs Add unit tests ensuring metadata is set/omitted in additional properties.
java/src/main/java/com/github/copilot/rpc/ToolDefinition.java Add metadata record component + factories + fluent modifier.
java/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java Emit null metadata argument in generated ToolDefinition(...) calls.
java/src/test/java/com/github/copilot/ToolDefinitionTest.java Add serialization tests for metadata presence/omission.
java/src/test/java/com/github/copilot/rpc/fixtures/StaticTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/StaticInvocationTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/SimpleTools$$CopilotToolMeta.java Update fixture constructor calls to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/OverrideTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/OptionalParamTools$$CopilotToolMeta.java Update fixture constructor calls to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/MultiReturnTools$$CopilotToolMeta.java Update fixture constructor calls to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/InvocationAwareTools$$CopilotToolMeta.java Update fixture constructor calls to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/DefaultValueTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/DateTimeTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/rpc/fixtures/ArgCoercionTools$$CopilotToolMeta.java Update fixture constructor call to include null metadata arg.
java/src/test/java/com/github/copilot/e2e/ErgonomicTestTools$$CopilotToolMeta.java Update fixture constructor calls to include null metadata arg.

Review details

  • Files reviewed: 26/26 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread java/src/main/java/com/github/copilot/rpc/ToolDefinition.java Outdated
Add an optional, opaque `metadata` bag to tool definitions across all SDK
languages and forward it verbatim over the session.create/resume RPC. This
lets hosts attach namespaced metadata to tools without expanding the typed
public contract; the runtime may recognize specific keys to inform
host-specific behavior. Unknown keys are round-tripped untouched.

Languages: nodejs (Tool.metadata + defineTool), python (Tool.metadata +
define_tool), go (Tool.Metadata), rust (Tool.metadata + with_metadata),
java (ToolDefinition.metadata + createWithMetadata), dotnet
(CopilotToolOptions.Metadata + wire ToolDefinition.Metadata). Tests added
per language for wire/serialization forwarding and omission when unset.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@belaltaher8
belaltaher8 force-pushed the belaltaher8/tool-meta-passthrough branch from 6fdc349 to 0d575bc Compare July 8, 2026 15:18
Comment thread dotnet/src/CopilotTool.cs Outdated
Comment thread go/types.go Outdated
Comment thread java/src/main/java/com/github/copilot/rpc/ToolDefinition.java
Comment thread java/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java Outdated
Comment thread dotnet/src/Client.cs Outdated
Comment thread rust/src/types.rs Outdated
Comment thread dotnet/src/CopilotTool.cs Outdated
belaltaher8 and others added 2 commits July 10, 2026 18:00
- dotnet: change Metadata value type to IDictionary<string, JsonNode?> for
  NativeAOT-safe serialization (CopilotToolOptions + wire ToolDefinition,
  FromAIFunction cast, unit test); drop redundant [JsonPropertyName("metadata")]
  since the Web camelCase policy already maps it; remove the <remarks> block
  from the Metadata property.
- Reword metadata doc comments across nodejs/python/go/rust/java to describe
  the bag opaquely without the SDK-vs-runtime/CLI distinction.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f
…-passthrough

# Conflicts:
#	python/test_client.py

@edburns edburns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see this comment.

belaltaher8 and others added 3 commits July 14, 2026 18:37
Address Java SME feedback so annotation-based tools reach parity with the
programmatic API and existing constructor call sites keep compiling.

- ToolDefinition: add a backward-compatible 7-arg constructor delegating to
  the canonical 8-arg with metadata=null.
- CopilotTool: add metadata() plus nested MetadataEntry/MetadataValue/
  MetadataFlag annotations (@target({})) with a shallow bool|str|flag-map
  representation, documenting the programmatic API for richer values.
- CopilotToolProcessor: generate the metadata constructor argument
  (Map.<String, Object>of(...) with an explicit type witness) instead of a
  hardcoded null; null when no metadata is present.
- Tests: processor generation cases (nested flags, absent, combined flags),
  ToolDefinition 7-arg/.metadata(...) copy/flag-chaining cases, and a
  fromObject metadata assertion; extend the SimpleTools fixture pair to emit
  a safeForTelemetry metadata map.
- ADR-005: update the generated snippet to the 8-arg shape and document the
  @copilotTool(metadata = ...) syntax and emitted shape.

Note: mvn verify / spotless:apply not run locally (no JDK/Maven in the dev
environment); relies on PR CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f
Reflow javadoc and wrap annotation/constructor args per the Eclipse
formatter (mvn spotless:apply). No behavioral change.

Verified locally: mvn spotless:check clean; ToolDefinitionTest (8),
ToolDefinitionFromObjectTest (31), CopilotToolProcessorTest (37) all pass on
JDK 26.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ab2c14cd-d2e1-4524-a6dc-e9c10899343c

@edburns edburns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #1864 (comment)
Do that and I'll give the green checkmark. Thanks.

test: assert null metadata arg in generated tool definition
Comment thread java/src/main/java/com/github/copilot/rpc/ToolDefinition.java Outdated

@SteveSandersonMS SteveSandersonMS left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment about terminology in a comment (trivial fix), but beside that this looks great. Thanks!

belaltaher8 and others added 2 commits July 15, 2026 12:49
…y state

Reword the 7-arg constructor's Javadoc to describe what the overload is (a
convenience constructor equivalent to the canonical one with metadata=null)
rather than its relationship to a specific change ("backward-compatible",
"retained so ... keep compiling after metadata was added"), which is only
meaningful in the context of the PR that introduced it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f
Comment thread rust/src/types.rs Outdated
HashMap serializes keys in a randomized order, unlike the sibling `parameters`
field (IndexMap) and the other SDKs (nodejs/python insertion order, Go sorted).
Switch the tool `metadata` bag to IndexMap<String, Value> so key order is
deterministic and consistent, avoiding non-reproducible wire output. No new
dependency; indexmap is already used by this struct.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants